package com.daoyi.redis;


import com.daoyi.redis.aop.GlobalLockAop;
import com.daoyi.redis.config.RedisConfig;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import javax.annotation.Resource;

/**
 * redis
 * @author daoyi
 * @date 2022-02-22
 */
@Configuration
@EnableAspectJAutoProxy
@EnableConfigurationProperties({RedisConfig.class})
public class RedisAutoConfiguration {


    @Resource
    private RedisConfig redisConfig;


    /**
     * 设置RedisTemplate 序列化 key为string  value 为fastJson 方便查看
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) throws Exception {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * 支持集群和单机
     * @return
     * @throws Exception
     */
    @Bean
    public RedissonClient redissonClient() throws Exception{
        Config config = new Config();

        if (redisConfig.getNodeAddress() == null) {
            throw new Exception("redis node address not found");
        }
        //单机
        if (redisConfig.getNodeAddress().size() == 1) {
            config.useSingleServer().setAddress(redisConfig.getNodeAddress().get(0));
            if (StringUtils.isNotEmpty(redisConfig.getPassword())){
                config.useSingleServer().setPassword(redisConfig.getPassword());
            }
        } else {
            //集群
            config.useClusterServers()
                .setScanInterval(2000)
                .addNodeAddress(redisConfig.getNodeAddress()
                        .toArray(new String[redisConfig.getNodeAddress().size()]));
            if (StringUtils.isNotEmpty(redisConfig.getPassword())){
                config.useClusterServers().setPassword(redisConfig.getPassword());
            }
        }
        return Redisson.create(config);
    }

    @Bean
    public GlobalLockAop lockAop(){
        return new GlobalLockAop();
    }
}